package com.gxar.navigation.server.base.interception;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gxar.common.entity.Result;
import com.gxar.common.entity.SystemCodeEnum;
import com.gxar.navigation.server.base.common.constant.QiMenConstant;
import com.gxar.navigation.server.base.model.qimen.UserProfile;
import com.gxar.navigation.server.base.reference.QiMenReference;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * 登录拦截器
 * 校验用户登录状态,将用户信息放入线程对象
 *
 * @author Linsy
 * @version 1.0
 * @created 2023/6/20
 */
@Component
@Slf4j
public class LoginInterception implements HandlerInterceptor {

    @Resource
    private QiMenReference qiMenReference;

    @Override
    public boolean preHandle(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) throws Exception {
        // 获取token
        String token = request.getHeader(QiMenConstant.ACCESS_TOKEN);
        if (StringUtils.isBlank(token)) {
            returnNoLogin(response);
            return false;
        }
        // 对登录信息进行校验
        JSONObject resultObject = qiMenReference.userInfo(token);
        Object data = resultObject.get("data");
        if (Objects.isNull(data)) {
            log.error("用户未登陆,查询登录状态data为空");
            returnNoLogin(response);
            return false;
        }
        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(data));
        Boolean isLogin = jsonObject.getBoolean("is_login");
        if (!isLogin) {
            log.error("用户未登陆,is_login不为true");
            returnNoLogin(response);
            return false;
        }
        UserProfile userProfile = new UserProfile();
        // TODO 用户信息解析

        // 存放用户线程对象
        LoginUserThread.put(userProfile);
        // 放行
        return true;
    }

    /**
     * 返回未登录的错误信息
     *
     * @param response ServletResponse
     */
    private void returnNoLogin(HttpServletResponse response) throws IOException {
        try (ServletOutputStream outputStream = response.getOutputStream()) {
            // 设置返回401 和响应编码
            response.setStatus(401);
            response.setContentType("Application/json;charset=utf-8");
            // 构造返回响应体
            Result<Object> result = Result.error(SystemCodeEnum.UN_AUTH);
            String resultString = JSON.toJSONString(result);
            outputStream.write(resultString.getBytes(StandardCharsets.UTF_8));
        }
    }

    /**
     * preHandle 返回true时清理对象
     *
     * @param request  请求
     * @param response 响应
     * @param handler  handler
     * @param ex       异常
     */
    @Override
    public void afterCompletion(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler, @Nullable Exception ex) {
        // 释放用户线程对象
        LoginUserThread.remove();
    }

}